#pragma once

#include <stdint.h>
#include <stdio.h>

#define MAX_ACTUATORS_COUNT 8

#ifdef __cplusplus
extern "C" {
#endif

typedef enum{
    EVENT_TASK
  , EVENT_T1
  , EVENT_TOF
  , EVENT_T2
  , EVENT_LAND
  , EVENT_ABORT
  , EVENT_STOP
  , EVENT_RESUM
  , EVENT_MAX

  , EVENT_UNKNOWN // need be last
} EVENT_t;

typedef enum{
    ABORT_FALSE
  , ABORT_TRUE
} ABORT_t;

typedef enum{
    FCACTION_EMPTY
  , FCACTION_TAKEOFF
  , FCACTION_LAND
  , FCACTION_STOP
  , FCACTION_RESUM
} FCACTION_t;

typedef enum{
    STATE_INIT
  , STATE_PRESTART
  , STATE_TAKEOFF
  , STATE_STOP
  , STATE_RESUM
  , STATE_HOLD
  , STATE_DESCENT
  , STATE_MAX

  , STATE_UNKNOWN // need be last
} STATE_t;

typedef enum{
    ACTION_T1
  , ACTION_TAKEOFF
  , ACTION_T2
  , ACTION_LAND
  , ACTION_RESET
  , ACTION_LAND_RESET
  , ACTION_REINIT
  , ACTION_STOP
  , ACTION_RESUM
  , ACTION_MAX
} ACTION_t;

/*
 * Взято из MAVSDK для совместимости.
 */
typedef enum{
  Unknown, /**< @brief Mode not known. */
  Ready, /**< @brief Armed and ready to take off. */
  Takeoff, /**< @brief Taking off. */
  Hold, /**< @brief Holding (hovering in place (or circling for fixed-wing vehicles). */
  Mission, /**< @brief In mission. */
  ReturnToLaunch, /**< @brief Returning to launch position (then landing). */
  Land, /**< @brief Landing. */
  Offboard, /**< @brief In 'offboard' mode. */
  FollowMe, /**< @brief In 'follow-me' mode. */
  Manual, /**< @brief In 'Manual' mode. */
  Altctl, /**< @brief In 'Altitude Control' mode. */
  Posctl, /**< @brief In 'Position Control' mode. */
  Acro, /**< @brief In 'Acro' mode. */
  Stabilized, /**< @brief In 'Stabilize' mode. */
  Rattitude, /**< @brief In 'Rattitude' mode. */
} FlightMode;

typedef enum{
  NoGps, /**< @brief No GPS connected. */
  NoFix, /**< @brief No position information, GPS is connected. */
  Fix2D, /**< @brief 2D position. */
  Fix3D, /**< @brief 3D position. */
  FixDgps, /**< @brief DGPS/SBAS aided 3D position. */
  RtkFloat, /**< @brief RTK float, 3D position. */
  RtkFixed, /**< @brief RTK Fixed, 3D position. */
} FixType;
// **********

typedef enum{
    FAIL_UNDEFINED = -1
  , FAIL_GPS
  , FAIL_BATTERY
  , FAIL_MOTOR
  , FAIL_POWER
  , FAIL_UNKNOWN
} FAIL_TYPE_t;

/*
 * Полетное задание.
 * Чтение: BC_TLM_SRV, BC_FTC
 * Запись: BC_CTL_SRV (полная)
 */
#pragma pack(push, 1)

typedef struct{
  FAIL_TYPE_t type;
  int time;
} fail_t;

typedef struct{
  uint16_t hight;
  int start_time;
  int hang_time;
} flight_task_t;

/*
 * Телеметрия контроллера полетного задания.
 * Чтение: BC_TLM_SRV
 * Запись: BC_FTC (неполная)
 */
typedef struct{
  STATE_t state_flg;
  int timer_1;
  int timer_2;
  EVENT_t event;
} ftc_tlm_t;

/*
 * Телеметрия полетного контроллера.
 * Чтение: BC_FTC, BC_TLM_SRV
 * Запись: BC_FC_TLM
 */
typedef struct{
  FlightMode flight_mode;
  FixType gps_fix;
  uint8_t actuators_count;
  int actuators[MAX_ACTUATORS_COUNT];
  float hight;
  float speed;
  double lat;
  double lon;
  fail_t fail;
} fc_tlm_t;

/*
 * Телеметрия бортового компьютера.
 * Чтение: BC_TLM_SRV
 * Запись: BC_TLM_SRV
 */
typedef struct{
  float temperature;
} bc_tlm_t;

typedef struct{
  fc_tlm_t fc_tlm;
  ftc_tlm_t ftc_tlm;
  bc_tlm_t bc_tlm;
} gcs_tlm_t;

#pragma pack(pop)


void flight_task_init(flight_task_t*);

void ftc_tlm_init(ftc_tlm_t*);

void fc_tlm_init(fc_tlm_t*);

void bc_tlm_init(bc_tlm_t*);

void gcs_tlm_print(const gcs_tlm_t tlm);

void fail_init(fail_t*);

#ifdef __cplusplus
};
#endif

